package com.authine.cloudpivot.ext.applicationservice.api;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.ext.applicationservice.base.ApplicationBaseService;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.PlatformConst;
import com.authine.cloudpivot.ext.dto.GatewayParam;
import com.authine.cloudpivot.ext.dto.GatewayParam2;
import com.authine.cloudpivot.ext.dto.GatewayResponse;
import com.authine.cloudpivot.ext.dto.OrderVendorDto;
import com.authine.cloudpivot.ext.dto.api.AgreeRefundVO;
import com.authine.cloudpivot.ext.dto.api.OrderDeliverVO;
import com.authine.cloudpivot.ext.dto.api.TempOrderReceipt;
import com.authine.cloudpivot.ext.dto.system.OrganizationDto;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.enums.order.OrderGoodsStatusEnum;
import com.authine.cloudpivot.ext.enums.order.OrderVendorStatusEnum;
import com.authine.cloudpivot.ext.enums.order.TraceTypeEnum;
import com.authine.cloudpivot.ext.eum.VendorOrderStatusV1Enum;
import com.authine.cloudpivot.ext.service.DockFinanceService;
import com.authine.cloudpivot.ext.service.OrderService;
import com.authine.cloudpivot.ext.service.OrderVendorBaseV1Service;
import com.authine.cloudpivot.ext.service.impl.DockFinanceServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderServiceImpl;
import com.authine.cloudpivot.ext.service.impl.OrderVendorBaseV1ServiceImpl;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.utils.system.OrgUtils;
import com.authine.cloudpivot.ext.utils.system.SessionUser;
import com.authine.cloudpivot.ext.utils.system.UserUtils;
import com.authine.cloudpivot.ext.vo.OrderGoodsV1VO;
import com.authine.cloudpivot.ext.vo.VendorOrderV1VO;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.utils.JsonParseObject;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;

import javax.ws.rs.POST;
import javax.ws.rs.Path;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * 供应商订单接口
 */
@Path("OrderVendorV1Service")
@Slf4j
public class OrderVendorV1Service extends ApplicationBaseService {
    private OrderService orderService = new OrderServiceImpl();
    private DockFinanceService dockFinanceService = new DockFinanceServiceImpl();
    private OrderVendorBaseV1Service orderVendorBaseV1Service = new OrderVendorBaseV1ServiceImpl();
    private TransactionTemplate transactionTemplate = ApplicationContextUtils.getBean(TransactionTemplate.class);


    /**
     * 供应商接单
     *
     * @return
     */
    @Path("vendorAccept")
    @POST
    @Operation(summary = "对外接口-供应商接单", tags = CUSTOM_SERVICE, description = "供应商接单")
    public GatewayResponse vendorAccept(@Parameter GatewayParam param) {
        String newOrderIds = (String) param.getBody().get("newOrderIds");
        List<String> orderIds = null == param.getBody().get("orderIds[]") ? null : (ArrayList<String>) param.getBody().get("orderIds[]");
        log.warn("[vendor-accept] begin:执行类：{},执行方法：vendorAccept（【供应商】接单）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        boolean b = false;
        if (StringUtils.isNotBlank(newOrderIds)) {
            if (CollectionUtils.isNotEmpty(orderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderIds = com.authine.cloudpivot.ext.utils.StringUtils.commaDelimitedTrimEmptyListString(newOrderIds);
            if (null == orderIds || orderIds.isEmpty()) return GatewayResponse.failed("参数不正确");

            b = orderService.orderTaking(orderIds);

   /*     applicationEventPublisher.publishEvent(new
                OrderRemoteSyncEvent(this, busProperties.getId(),
                "**", OrderRemoteSyncEventParam.builder().type(OrderSyncEventTypeEnum.OrderTaking).orderVendorIds(orderIds).build()));
*/
        } else {
            log.warn("使用过期参数 [vendor-accept]-orderIds[] , {}", StringUtils.join(orderIds, ","));
        }
        if (b) {
            return GatewayResponse.success(orderIds.size(), "已接单", orderIds);
        } else {
            return GatewayResponse.failed("接单失败！");
        }
    }

    /**
     * 【供应商/平台】审批退款
     *
     * @return
     */
    @Path("vendorApproveRefund")
    @POST
    @Operation(summary = "对外接口-审批退款", tags = CUSTOM_SERVICE, description = "审批客户退款申请单")
    public GatewayResponse vendorApproveRefund(@Parameter GatewayParam param) {
        String newOrderGoodsIds = (String) param.getBody().get("newOrderGoodsIds");
        String type = (String) param.getBody().get("type");
        List<String> orderGoodsIds = null == param.getBody().get("orderGoodsIds[]") ? null : (ArrayList<String>) param.getBody().get("orderGoodsIds[]");
        Boolean agree = (Boolean) param.getBody().get("agree");
        log.warn("[approve-return] begin:执行类：{},执行方法：approveRefund（【供应商/平台】审批退款）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        if (StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = com.authine.cloudpivot.ext.utils.StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        } else {
            log.warn("使用过期参数 [vendor-approve-refund]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
        }
        if (orderGoodsIds == null || orderGoodsIds.isEmpty() || null == agree) {
            return GatewayResponse.failed("参数不正确");
        }
        SingleResponse result = orderService.approvalRefund(new AgreeRefundVO(orderGoodsIds, agree, null, null, null, null, null, type));
        log.warn("[approve-return] end:执行类：{},执行方法：approveRefund（【供应商/平台】审批退款）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        return GatewayResponse.success(orderGoodsIds.size(), agree ? "同意退款成功！" : "拒绝退款成功！", orderGoodsIds);
    }

    /**
     * 【供应商/平台】确定到货
     */
    @Path("vendorConfirmReceived")
    @POST
    @Operation(summary = "对外接口-确定到货", tags = CUSTOM_SERVICE, description = "客户退货后确认到货")
    public GatewayResponse vendorConfirmReceived(@Parameter GatewayParam param) {
        String newOrderGoodsIds = (String) param.getBody().get("newOrderGoodsIds");
        List<String> orderGoodsIds = null == param.getBody().get("orderGoodsIds[]") ? null : (ArrayList<String>) param.getBody().get("orderGoodsIds[]");
        if (StringUtils.isNotBlank(newOrderGoodsIds)) {
            if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderGoodsIds = com.authine.cloudpivot.ext.utils.StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
        } else {
            log.warn("使用过期参数 [confirm-received]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
        }
        return GatewayResponse.success("确认到货", orderService.confireReturn(orderGoodsIds));
    }

    /**
     * 【供应商】发货(供应商对接新增, 跳过接单, 直接发货)
     */
    @Path("vendorDeliverGoods")
    @POST
    @Operation(summary = "对外接口-发货", tags = CUSTOM_SERVICE, description = "客户退货后确认到货")
    public GatewayResponse vendorDeliverGoods(@Parameter GatewayParam param) {
        String newOrderGoodsIds = (String) param.getBody().get("newOrderGoodsIds");
        List<String> orderGoodsIds = null == param.getBody().get("orderGoodsIds[]") ? null : (ArrayList<String>) param.getBody().get("orderGoodsIds[]");
        String waybill = (String) param.getBody().get("waybill");
        String logistics = (String) param.getBody().get("logistics");
        log.warn("[vendor-deliver] begin:执行类：{},执行方法：deliver（【供应商对接】发货）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        Map<String, Object> result = new HashMap<>();
        try {
            if (StringUtils.isNotBlank(newOrderGoodsIds)) {
                if (CollectionUtils.isNotEmpty(orderGoodsIds)) {
                    return GatewayResponse.failed("请勿同时传递过期参数类型");
                }
                orderGoodsIds = com.authine.cloudpivot.ext.utils.StringUtils.commaDelimitedTrimEmptyListString(newOrderGoodsIds);
            } else {
                log.warn("使用过期参数 [deliver-goods]-orderGoodsIds[] , {}", org.apache.commons.lang3.StringUtils.join(orderGoodsIds, ","));
            }
            if (CollectionUtils.isEmpty(orderGoodsIds)) {
                return GatewayResponse.failed("参数不正确");
            }
            //当前供应商ID
            List<String> orgIds = Collections.singletonList((String) getCurrentDept().get("id"));

            List<Map<String, Object>> orderGoodsEntities = getOrderVendorGoodsByGoodsId(orderGoodsIds, orgIds);
            if (orderGoodsIds.size() != orderGoodsEntities.size()) {
                return GatewayResponse.failed("部分订单商品不存在, 请检查!");
            }
            Set<String> vendorOrderIds = orderGoodsEntities.stream().filter(e ->
                    OrderVendorStatusEnum.UpcomingConfirm.name().equals(e.get("order_vendor_goods_status"))).map(e -> (String) e.get("id")).collect(Collectors.toSet());
            if (!vendorOrderIds.isEmpty()) {
                orderService.orderTaking(new ArrayList(vendorOrderIds));
            }
            result = deliveryGoods(orderGoodsIds, waybill, logistics);
        } catch (Exception e) {
            return GatewayResponse.failed("请求失败");
        } finally {
            log.warn("[vendor-deliver] end:执行类：{},执行方法：deliver（【供应商对接】发货）,请求人{}" + this.getClass().getName(), RequestContext.getCorpLoginId());
        }
        return GatewayResponse.success("发货成功", result);
    }

    /**
     * 根据id查询供应商订单
     */
    @Path("listVendorOrderDetail")
    @POST
    @Operation(summary = "对外接口-根据id查询供应商订单", tags = CUSTOM_SERVICE, description = "根据id查询供应商订单")
    public GatewayResponse listVendorOrderDetail(@Parameter GatewayParam param) {
        String id = (String) param.getBody().get("id");
        return GatewayResponse.success(1, getOrderVendorGoodsByGoodsId(Collections.singletonList(id), null));
    }


    @Path("vendorById")
    @POST
    @Operation(summary = "对外接口-根据id查询供应商订单(vendorById)", tags = CUSTOM_SERVICE, description = "根据id查询供应商订单")
    public GatewayResponse vendorById(@Parameter GatewayParam param) {
        log.info("[vendorById] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());

        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");

        // 订单Id
        String vendorOrderId = (String) param.getQuery().get("id");
        Assert.isTrue(StringUtils.isNotBlank(vendorOrderId), "请求参数查询条件  不能为空");

        //todo sessionUser.isPm()
        UserDto currentUser = UserUtils.getCurrentUser();
        Assert.notNull(currentUser, "当前登录用户 不能为空");
        List<SelectorFormat> organization = currentUser.getOrganization_id();

        Map<String, Object> vendorOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).eq("id", vendorOrderId).queryForMap();

        if (null == vendorOrder) {
            return GatewayResponse.success(0, null);
        }

        //获取客户订单数据
        Map<String, Object> customerOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).eq("id", vendorOrder.get("order_customer_id")).queryForMap();
        Assert.notNull(customerOrder, "查询客户订单 为空");

        VendorOrderV1VO vendorOrderV1VO = VendorOrderV1VO.of().setOrderId(String.valueOf(vendorOrder.get("id")))
                .setCustomerOrderId(String.valueOf(vendorOrder.get("order_customer_id")))
                .setStatus(String.valueOf(vendorOrder.get("order_vendor_status")))
                .setMemo(String.valueOf(vendorOrder.get("memo")))
                .setErpPO(String.valueOf(vendorOrder.get("erp_po")))
                .setReceiver(String.valueOf(vendorOrder.get("receiver")))
                .setPhone(String.valueOf(vendorOrder.get("phone")))
                .setPostal(String.valueOf(vendorOrder.get("postal")))
                .setAddress(String.valueOf(vendorOrder.get("address")))
                .setTaxPayable(new BigDecimal(String.valueOf(vendorOrder.get("tax_payable"))))
                .setPretaxTotal(new BigDecimal(String.valueOf(vendorOrder.get("pretax_total"))))
                .setTotal(new BigDecimal(String.valueOf(vendorOrder.get("total"))))
                .setTaxPayableFreight(new BigDecimal(String.valueOf(vendorOrder.get("tax_payable_freight"))))
                .setFreight(new BigDecimal(String.valueOf(vendorOrder.get("freight"))))
                .setPretaxAmount(new BigDecimal(String.valueOf(vendorOrder.get("pretax_amount"))))
                .setAmount(new BigDecimal(String.valueOf(vendorOrder.get("amount"))))
                .setMemberName(String.valueOf(customerOrder.get("place_order_fullname")))
                .setTime(Utils.strToDate(String.valueOf(vendorOrder.get("createdTime"))))
                .setCustomerOrgName(String.valueOf(customerOrder.get("organization_name")))
                .setOrderType(String.valueOf(customerOrder.get("source")));


        //查询 供应商订单商品
        List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).eq("order_vendor_id", vendorOrderId).queryForList();
        Assert.isTrue(!CollectionUtils.isEmpty(vendorOrderGoodsList), "供应商订单商品 信息  不能为空");

        List<String> relationIdList = vendorOrderGoodsList.stream().map(e -> String.valueOf(e.get("relation_id"))).collect(Collectors.toList());
        List<Map<String, Object>> goodsRelationList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RELATION).selectField("*").in("id", relationIdList).queryForList();

        Assert.isTrue(!CollectionUtils.isEmpty(goodsRelationList), "查询供应商订单商品关系信息 不能为空");

        Map<String, Map<String, Object>> relationMap = goodsRelationList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

        List<OrderGoodsV1VO> orderGoodsV1VOList = new LinkedList<>();
        for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {

            Map<String, Object> relation = relationMap.getOrDefault(String.valueOf(vendorOrderGoods.get("relation_id")), null);
            Map<String, Object> inquiry = null;
            if (null != relation) {
                //询价
                String inquiryId = String.valueOf(relation.get("inquiry_id"));
                inquiry = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY).selectField("*").eq("id", inquiryId).queryForMap();
            }

            //报价商品信息
            Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", vendorOrderGoods.get("goods_id")).queryForMap();
            Assert.notNull(quotationGoods, "查询报价商品 为空");

            OrderGoodsV1VO orderGoodsV1VO = OrderGoodsV1VO.of().setOrderGoodsId(String.valueOf(vendorOrderGoods.get("id")))
                    .setClientOrderGoodsId(String.valueOf(vendorOrderGoods.get("client_order_goods_id")))
                    .setCustomerOrderId(String.valueOf(vendorOrderGoods.get("order_customer_id")))
                    .setVendorOrderId(String.valueOf(vendorOrderGoods.get("order_vendor_id")))
                    .setVendorName(String.valueOf(vendorOrderGoods.get("vendor_organization_name")))
                    .setName(String.valueOf(vendorOrderGoods.get("name")))
                    .setBrand(String.valueOf(vendorOrderGoods.get("brand")))
                    .setModel(String.valueOf(vendorOrderGoods.get("model")))
                    .setSpec(String.valueOf(vendorOrderGoods.get("spec")))
                    .setSku(String.valueOf(vendorOrderGoods.get("sku")))
                    .setBarCode(String.valueOf(vendorOrderGoods.get("bar_code")))
                    .setUnspsc(String.valueOf(vendorOrderGoods.get("unspsc")))
                    .setGoldenTax(String.valueOf(vendorOrderGoods.get("golden_tax")))
                    .setImages(String.valueOf(vendorOrderGoods.get("images")))
                    .setDescription(String.valueOf(vendorOrderGoods.get("description")))
                    .setTechnical(String.valueOf(vendorOrderGoods.get("technical")))
                    .setPackaging(String.valueOf(vendorOrderGoods.get("packaging")))
                    .setMemo(String.valueOf(vendorOrderGoods.get("memo")))
                    .setUnit(String.valueOf(vendorOrderGoods.get("unit")))
                    .setPackageUnit(String.valueOf(vendorOrderGoods.get("package_unit")))
                    .setNum(new BigDecimal(String.valueOf(vendorOrderGoods.get("quantity"))))
                    .setPackageNum(new BigDecimal(String.valueOf(vendorOrderGoods.get("package_quantity"))))
                    .setDelivery(Integer.valueOf(String.valueOf(vendorOrderGoods.get("delivery"))))
                    .setTaxRate(new BigDecimal(String.valueOf(vendorOrderGoods.get("tax_rate"))))
                    .setTaxRateFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("freight_rate"))))
                    .setPretaxPrice(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_price"))))
                    .setPrice(new BigDecimal(String.valueOf(vendorOrderGoods.get("price"))))
                    .setPretaxFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_freight"))))
                    .setFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("freight"))))
                    .setPretaxTotal(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_total"))))
                    .setTotal(new BigDecimal(String.valueOf(vendorOrderGoods.get("total"))))
                    .setPretaxAmount(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_amount"))))
                    .setAmount(new BigDecimal(String.valueOf(vendorOrderGoods.get("amount"))))
                    .setStatus(String.valueOf(vendorOrderGoods.get("order_vendor_goods_status")))
                    .setAttachment(String.valueOf(vendorOrderGoods.get("attachment")))
                    .setOrderType(String.valueOf(customerOrder.get("type")))
                    .setCustomerOrgName(String.valueOf(vendorOrderGoods.get("customer_organization_name")))
                    .setMemberName(String.valueOf(customerOrder.get("place_order_fullname"))) //实际下单人？
                    .setTime(Utils.strToDate(String.valueOf(vendorOrder.get("createdTime"))))
                    .setClarifyTips(quotationGoods == null ? null : String.valueOf(quotationGoods.get("clarify_tips")))
                    .setCategory(String.valueOf(vendorOrderGoods.get("category")))
                    .setRemarkMessages(quotationGoods == null ? null : String.valueOf(quotationGoods.get("remark_message")))
                    .setQuotationGoodsId(String.valueOf(vendorOrderGoods.get("goods_id")))
                    .setDemandDeptName(inquiry == null ? null : String.valueOf(inquiry.get("department_name")))
                    .setInquiryMemberName(inquiry == null ? null : String.valueOf(inquiry.get("member_name")));

            //已退数量
            List<Map<String, Object>> orderGoodsReturnList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).queryForList();

            String returnStatus = null;
            BigDecimal refundedNum = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(orderGoodsReturnList)) {
                returnStatus = String.valueOf(orderGoodsReturnList.get(0).get("order_goods_returns_status"));
                for (Map<String, Object> orderGoodsReturn : orderGoodsReturnList) {
                    if (null == orderGoodsReturn.get("quantity")) {
                        continue;
                    }
                    BigDecimal quantity = new BigDecimal(String.valueOf(orderGoodsReturn.get("quantity")));
                    refundedNum = quantity.add(refundedNum);
                }
            }

            //已发数量
            List<Map<String, Object>> orderTraceList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).eq("type", TraceTypeEnum.ShippingLogistics).queryForList();
            BigDecimal deliveredNum = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(orderTraceList)) {
                for (Map<String, Object> orderTrace : orderTraceList) {
                    if (null == orderTrace.get("quantity")) {
                        continue;
                    }
                    BigDecimal quantity = new BigDecimal(String.valueOf(orderTrace.get("quantity")));
                    deliveredNum = quantity.add(deliveredNum);
                }
            }
            //已收数量
            List<Map<String, Object>> orderGoodsAcceptList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_ACCEPT).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).queryForList();
            BigDecimal receivedNum = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(orderGoodsAcceptList)) {
                for (Map<String, Object> orderGoodsAccept : orderGoodsAcceptList) {
                    if (null == orderGoodsAccept.get("quantity")) {
                        continue;
                    }
                    BigDecimal quantity = new BigDecimal(String.valueOf(orderGoodsAccept.get("quantity")));
                    receivedNum = quantity.add(receivedNum);
                }
            }

            orderGoodsV1VO.setReturnStatus(returnStatus);
            orderGoodsV1VO.setRefundedNum(refundedNum);
            orderGoodsV1VO.setDeliveredNum(deliveredNum);
            orderGoodsV1VO.setReceivedNum(receivedNum);
            orderGoodsV1VO.setVendorOrderStatusEnum(String.valueOf(vendorOrder.get("order_vendor_status")));

            BigDecimal quantity = new BigDecimal(String.valueOf(vendorOrderGoods.get("quantity")));
            BigDecimal returnedNum = new BigDecimal(String.valueOf(vendorOrderGoods.get("returned_num")));
            orderGoodsV1VO.setDeliverableNum(quantity.subtract(refundedNum).subtract(deliveredNum).add(returnedNum));
            orderGoodsV1VO.setClientVendorGoodsId(String.valueOf(vendorOrderGoods.get("client_order_vendor_goods_id")));
            orderGoodsV1VOList.add(orderGoodsV1VO);
        }

        vendorOrderV1VO.setOrderGoods(orderGoodsV1VOList);
        log.info("[vendorById] end  >>>>>>>");
        return GatewayResponse.success(1, "查询成功! ", vendorOrderV1VO);

    }


    @Path("vendorByPage")
    @POST
    @Operation(summary = "对外接口-分页查询供应商订单(customerPage)", tags = CUSTOM_SERVICE, description = "分页查询供应商订单")
    public GatewayResponse vendorByPage(@Parameter GatewayParam param) {
        log.info("[vendorByPage] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());

        Assert.notNull(param.getQuery(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");

        //订单id集合(逗号分隔)
        String newOrderIds = (String) param.getQuery().get("newOrderIds");
        //客户订单id集合(逗号分隔)
        String newCustomerOrderIds = (String) param.getQuery().get("newCustomerOrderIds");
        //订单状态码 0:全部 1:新建 2:待接单 3:交易中 4:已关闭 5:已完成
        Integer statusCode = (Integer) param.getQuery().get("statusCode");
        //当前第几页（默认1）
        Integer page = (Integer) param.getQuery().get("page");
        //每页条目数（limit<=100,默认20）
        Integer limit = (Integer) param.getQuery().get("limit");

        List<String> orderIds = (List<String>) param.getQuery().get("orderIds[]");
        List<String> customerOrderIds = (List<String>) param.getQuery().get("customerOrderIds[]");

        if (org.apache.commons.lang3.StringUtils.isNotBlank(newOrderIds)) {
            if (CollectionUtils.isNotEmpty(orderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            orderIds = StringUtils.commaDelimitedTrimEmptyListString(newOrderIds);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(newCustomerOrderIds)) {
            if (CollectionUtils.isNotEmpty(customerOrderIds)) {
                return GatewayResponse.failed("请勿同时传递过期参数类型");
            }
            customerOrderIds = StringUtils.commaDelimitedTrimEmptyListString(newCustomerOrderIds);
        }

        OrderVendorDto orderVendorDto = new OrderVendorDto();
        orderVendorDto.setIds(orderIds);
        orderVendorDto.setOrderCustomerIdList(customerOrderIds);
        orderVendorDto.setVendorOrderStatusV1Enum(null == statusCode ? null : VendorOrderStatusV1Enum.get(statusCode));
        orderVendorDto.setPageIndex(page);
        orderVendorDto.setPageSize(limit);
        if (!sessionUser.isPm()) {
            orderVendorDto.setVendorIdList(Arrays.asList(sessionUser.getCurrentOrgID()));
        }

        BOList boList = orderVendorBaseV1Service.vendorOrderByPageContainVendor(orderVendorDto);
        if (null == boList || 0 == boList.getTotal() || null == boList.getData()) {
            return GatewayResponse.success("查询成功");
        }

        log.info("查询的数据 result:{}", boList);
        int total = boList.getTotal();
        List<VendorOrderV1VO> vendorOrderV1VOList = new ArrayList<>();
        for (Map<String, Object> vendorOrder : boList.getData()) {
            log.info("for循环 vendorOrder:{}", vendorOrder);

            //获取客户订单数据
            Map<String, Object> customerOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).eq("id", String.valueOf(vendorOrder.get("order_customer_id"))).queryForMap();
            Assert.notNull(customerOrder, "查询客户订单 为空");

            VendorOrderV1VO vendorOrderV1VO = VendorOrderV1VO.of().setOrderId(String.valueOf(vendorOrder.get("id")))
                    .setCustomerOrderId(String.valueOf(vendorOrder.get("order_customer_id")))
                    .setStatus(String.valueOf(vendorOrder.get("order_vendor_status")))
                    .setMemo(String.valueOf(vendorOrder.get("memo")))
                    .setErpPO(String.valueOf(vendorOrder.get("erp_po")))
                    .setReceiver(String.valueOf(vendorOrder.get("receiver")))
                    .setPhone(String.valueOf(vendorOrder.get("phone")))
                    .setPostal(String.valueOf(vendorOrder.get("postal")))
                    .setAddress(String.valueOf(vendorOrder.get("address")))
                    .setTaxPayable(new BigDecimal(String.valueOf(vendorOrder.get("tax_payable"))))
                    .setPretaxTotal(new BigDecimal(String.valueOf(vendorOrder.get("pretax_total"))))
                    .setTotal(new BigDecimal(String.valueOf(vendorOrder.get("total"))))
                    .setTaxPayableFreight(new BigDecimal(String.valueOf(vendorOrder.get("tax_payable_freight"))))
                    .setFreight(new BigDecimal(String.valueOf(vendorOrder.get("freight"))))
                    .setPretaxAmount(new BigDecimal(String.valueOf(vendorOrder.get("pretax_amount"))))
                    .setAmount(new BigDecimal(String.valueOf(vendorOrder.get("amount"))))
                    .setMemberName(String.valueOf(customerOrder.get("place_order_fullname")))
                    .setTime(Utils.strToDate(String.valueOf(vendorOrder.get("createdTime"))))
                    .setCustomerOrgName(String.valueOf(customerOrder.get("organization_name")))
                    .setOrderType(String.valueOf(customerOrder.get("source")));


            //查询 供应商订单商品
            List<Map<String, Object>> vendorOrderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR_GOODS).eq("order_vendor_id", vendorOrder.get("id")).queryForList();
            Assert.isTrue(!CollectionUtils.isEmpty(vendorOrderGoodsList), "供应商订单商品 信息  不能为空");

            List<String> relationIdList = vendorOrderGoodsList.stream().map(e -> String.valueOf(e.get("relation_id"))).collect(Collectors.toList());
            List<Map<String, Object>> goodsRelationList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RELATION).selectField("*").in("id", relationIdList).queryForList();

            Map<String, Map<String, Object>> relationMap = null;
            if (!CollectionUtils.isEmpty(goodsRelationList)) {
                relationMap = goodsRelationList.stream().collect(Collectors.toMap(e -> String.valueOf(e.get("id")), ogr -> ogr));

            }

            List<OrderGoodsV1VO> orderGoodsV1VOList = new LinkedList<>();
            for (Map<String, Object> vendorOrderGoods : vendorOrderGoodsList) {

                Map<String, Object> relation = null == relationMap ? null : relationMap.getOrDefault(String.valueOf(vendorOrderGoods.get("relation_id")), null);
                Map<String, Object> inquiry = null;
                if (null != relation) {
                    //询价
                    String inquiryId = String.valueOf(relation.get("inquiry_id"));
                    inquiry = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY).selectField("*").eq("id", inquiryId).queryForMap();
                }

                //报价商品信息
                Map<String, Object> quotationGoods = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS).selectField("*").eq("id", vendorOrderGoods.get("goods_id")).queryForMap();
                Assert.notNull(quotationGoods, "查询报价商品 为空");

                OrderGoodsV1VO orderGoodsV1VO = OrderGoodsV1VO.of().setOrderGoodsId(String.valueOf(vendorOrderGoods.get("id")))
                        .setClientOrderGoodsId(String.valueOf(vendorOrderGoods.get("client_order_goods_id")))
                        .setCustomerOrderId(String.valueOf(vendorOrderGoods.get("order_customer_id")))
                        .setVendorOrderId(String.valueOf(vendorOrderGoods.get("order_vendor_id")))
                        .setVendorName(String.valueOf(vendorOrderGoods.get("vendor_organization_name")))
                        .setName(String.valueOf(vendorOrderGoods.get("name")))
                        .setBrand(String.valueOf(vendorOrderGoods.get("brand")))
                        .setModel(String.valueOf(vendorOrderGoods.get("model")))
                        .setSpec(String.valueOf(vendorOrderGoods.get("spec")))
                        .setSku(String.valueOf(vendorOrderGoods.get("sku")))
                        .setBarCode(String.valueOf(vendorOrderGoods.get("bar_code")))
                        .setUnspsc(String.valueOf(vendorOrderGoods.get("unspsc")))
                        .setGoldenTax(String.valueOf(vendorOrderGoods.get("golden_tax")))
                        .setImages(String.valueOf(vendorOrderGoods.get("images")))
                        .setDescription(String.valueOf(vendorOrderGoods.get("description")))
                        .setTechnical(String.valueOf(vendorOrderGoods.get("technical")))
                        .setPackaging(String.valueOf(vendorOrderGoods.get("packaging")))
                        .setMemo(String.valueOf(vendorOrderGoods.get("memo")))
                        .setUnit(String.valueOf(vendorOrderGoods.get("unit")))
                        .setPackageUnit(String.valueOf(vendorOrderGoods.get("package_unit")))
                        .setNum(new BigDecimal(String.valueOf(vendorOrderGoods.get("quantity"))))
                        .setPackageNum(new BigDecimal(String.valueOf(vendorOrderGoods.get("package_quantity"))))
                        .setDelivery(Integer.valueOf(String.valueOf(vendorOrderGoods.get("delivery"))))
                        .setTaxRate(new BigDecimal(String.valueOf(vendorOrderGoods.get("tax_rate"))))
                        .setTaxRateFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("freight_rate"))))
                        .setPretaxPrice(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_price"))))
                        .setPrice(new BigDecimal(String.valueOf(vendorOrderGoods.get("price"))))
                        .setPretaxFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_freight"))))
                        .setFreight(new BigDecimal(String.valueOf(vendorOrderGoods.get("freight"))))
                        .setPretaxTotal(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_total"))))
                        .setTotal(new BigDecimal(String.valueOf(vendorOrderGoods.get("total"))))
                        .setPretaxAmount(new BigDecimal(String.valueOf(vendorOrderGoods.get("pretax_amount"))))
                        .setAmount(new BigDecimal(String.valueOf(vendorOrderGoods.get("amount"))))
                        .setStatus(String.valueOf(vendorOrderGoods.get("order_vendor_goods_status")))
                        .setAttachment(String.valueOf(vendorOrderGoods.get("attachment")))
                        .setOrderType(String.valueOf(customerOrder.get("type")))
                        .setCustomerOrgName(String.valueOf(vendorOrderGoods.get("customer_organization_name")))
                        .setMemberName(String.valueOf(customerOrder.get("place_order_fullname"))) //实际下单人？
                        .setTime(Utils.strToDate(String.valueOf(vendorOrder.get("createdTime"))))
                        .setClarifyTips(quotationGoods == null ? null : String.valueOf(quotationGoods.get("clarify_tips")))
                        .setCategory(String.valueOf(vendorOrderGoods.get("category")))
                        .setRemarkMessages(quotationGoods == null ? null : String.valueOf(quotationGoods.get("remark_message")))
                        .setQuotationGoodsId(String.valueOf(vendorOrderGoods.get("goods_id")))
                        .setDemandDeptName(inquiry == null ? null : String.valueOf(inquiry.get("department_name")))
                        .setInquiryMemberName(inquiry == null ? null : String.valueOf(inquiry.get("member_name")));

                //已退数量
                List<Map<String, Object>> orderGoodsReturnList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_RETURNS).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).queryForList();

                String returnStatus = null;
                BigDecimal refundedNum = BigDecimal.ZERO;
                if (!CollectionUtils.isEmpty(orderGoodsReturnList)) {
                    returnStatus = String.valueOf(orderGoodsReturnList.get(0).get("order_goods_returns_status"));
                    for (Map<String, Object> orderGoodsReturn : orderGoodsReturnList) {
                        if (null == orderGoodsReturn.get("quantity")) {
                            continue;
                        }
                        BigDecimal quantity = new BigDecimal(String.valueOf(orderGoodsReturn.get("quantity")));
                        refundedNum = quantity.add(refundedNum);
                    }
                }

                //已发数量
                List<Map<String, Object>> orderTraceList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).eq("type", TraceTypeEnum.ShippingLogistics).queryForList();
                BigDecimal deliveredNum = BigDecimal.ZERO;
                if (!CollectionUtils.isEmpty(orderTraceList)) {
                    for (Map<String, Object> orderTrace : orderTraceList) {
                        if (null == orderTrace.get("quantity")) {
                            continue;
                        }
                        BigDecimal quantity = new BigDecimal(String.valueOf(orderTrace.get("quantity")));
                        deliveredNum = quantity.add(deliveredNum);
                    }
                }
                //已收数量
                List<Map<String, Object>> orderGoodsAcceptList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_GOODS_ACCEPT).eq("order_vendor_goods_id", vendorOrderGoods.get("id")).queryForList();
                BigDecimal receivedNum = BigDecimal.ZERO;
                if (!CollectionUtils.isEmpty(orderGoodsAcceptList)) {
                    for (Map<String, Object> orderGoodsAccept : orderGoodsAcceptList) {
                        if (null == orderGoodsAccept.get("quantity")) {
                            continue;
                        }
                        BigDecimal quantity = new BigDecimal(String.valueOf(orderGoodsAccept.get("quantity")));
                        receivedNum = quantity.add(receivedNum);
                    }
                }

                orderGoodsV1VO.setReturnStatus(returnStatus);
                orderGoodsV1VO.setRefundedNum(refundedNum);
                orderGoodsV1VO.setDeliveredNum(deliveredNum);
                orderGoodsV1VO.setReceivedNum(receivedNum);
                orderGoodsV1VO.setVendorOrderStatusEnum(String.valueOf(vendorOrder.get("order_vendor_status")));

                BigDecimal quantity = new BigDecimal(String.valueOf(vendorOrderGoods.get("quantity")));
                BigDecimal returnedNum = new BigDecimal(String.valueOf(vendorOrderGoods.get("returned_num")));
                orderGoodsV1VO.setDeliverableNum(quantity.subtract(refundedNum).subtract(deliveredNum).add(returnedNum));
                orderGoodsV1VO.setClientVendorGoodsId(String.valueOf(vendorOrderGoods.get("client_order_vendor_goods_id")));
                orderGoodsV1VOList.add(orderGoodsV1VO);
            }

            vendorOrderV1VO.setOrderGoods(orderGoodsV1VOList);
            vendorOrderV1VOList.add(vendorOrderV1VO);
        }

        log.info("[vendorByPage] end  >>>>>>>");
        return GatewayResponse.success(total, "查询成功", vendorOrderV1VOList);
    }


    @Path("vendorDeliver")
    @POST
    @Operation(summary = "对外接口-供应商发货(deliver)", tags = CUSTOM_SERVICE, description = "供应商发货(deliver)")
    public GatewayResponse vendorDeliver(@Parameter GatewayParam2 param2) {

        log.info("[vendorDeliver] begin:执行类：{},请求人:{}", this.getClass().getName(), RequestContext.getCorpLoginId());
        Assert.notNull(param2.getBody(), "请求参数查询条件 不能为空");
        SessionUser sessionUser = new SessionUser();
        if (null == sessionUser.get()) throw new BizException("未获取到登录信息!");

        List<OrderDeliverVO> orderDeliverVOS = JsonParseObject.parseObject(JSON.toJSONString(param2.getBody()), OrderDeliverVO.class);
        //验证发货数据
        String errorMessage = orderVendorBaseV1Service.verifyOrderDeliverVO(orderDeliverVOS);
        //验证失败直接返回
        if (null != errorMessage && errorMessage.length() > 0) {
            log.info("vendorDeliver-verify-fail-result:{},param:{}", errorMessage, orderDeliverVOS);
            return GatewayResponse.failed(errorMessage);
        }

        TempOrderReceipt tempOrderReceipt = transactionTemplate.execute(result -> orderVendorBaseV1Service.deliver(orderDeliverVOS, sessionUser));

        //todo publishEvent
//        if (!CollectionUtils.isEmpty(data.getTraceIds())) {
//            applicationEventPublisher.publishEvent(new
//                    OrderRemoteSyncEvent(this, busProperties.getId(),
//                    "**", OrderRemoteSyncEventParam.builder()
//                    .type(OrderSyncEventTypeEnum.SaveTransport).traceIds(data.getTraceIds()).orderVendorIds(new ArrayList<>(data.getVendorOrderIds())).build()));
//        }

        log.info("[vendorDeliver] end  >>>>>>>");
        return GatewayResponse.success("发货成功");
    }
}
